<?php
/**
 * File containing the BRail_Security_AuthenticationService class.
 * @package BRail_Security
 */

/**
 * Create authenticated user from ticket
 *
 * Example:
 * <code>
 * try {
 *      $authenticationService = new BRail_Security_AuthenticationService(
 *          'url' => 'http://...',
 *          'user' => '...',
 *          'key' => '...'
 *          'http://inf01atriuap07/dev-security-role/roleprovider.asmx?WSDL',
 *      );
 *      $authenticationService->createFromTicket(
 *          $_GET['t'], 'AxxxC', 'object', 'function'
 *      );
 * } catch (BRail_Security_TicketException $e) {
 *     echo 'Error while retrieving ticket information: ' . $e->getMessage() . PHP_EOL;
 * }
 * </code>
 *
 * @package BRail_Security
 */
class BRail_Security_AuthenticationService
{
    /**
     * URL of the Role Provider WSDL
     *
     * @var string
     */
    private $roleProviderWSDL;

    /**
     * Configuration of the security service
     *
     * @var array
     */
    private $securityServiceConfiguration;

    /**
     * @param string $url
     * @param string $user
     * @param string $key
     * @param string $roleProviderWSDL [optional]
     */
    public function __construct($url, $user, $key, $roleProviderWSDL = null)
    {
        $this->securityServiceConfiguration = array(
            'url'  => $url,
            'user' => $user,
            'key'  => $key
        );
        $this->roleProviderWSDL = $roleProviderWSDL;
    }

    /**
     * Creates a BRail_Security_AuthenticatedUser from a ticket
     *
     * @param string $ticket
     * @param string $applicationID
     * @param string $objectID
     * @param string $functionID
     * @throws BRail_Security_InvalidTicketException
     *         the ticket string does not validate
     * @throws BRail_Security_IncorrectTicketUsageException
     *         the ticket has been made for another applicationID/objectID/functionID combination
     * @return BRail_Security_AuthenticatedUser
     */
    public function createFromTicket($ticket, $applicationID, $objectID, $functionID)
    {
        // initialize the proxy
        // - url of the webservice
        // - user referenced in the BRail Security database
        // - secret key of the user
        $securityProxy = new BRail_Security_Services_Proxy(
            $this->securityServiceConfiguration['url'],
            $this->securityServiceConfiguration['user'],
            $this->securityServiceConfiguration['key']
        );

        $userInformation = $securityProxy->validateAndRedeemTicket($ticket);

        if ($userInformation->applicationId != $applicationID or
            $userInformation->objectId != $objectID or
            $userInformation->functionId != $functionID) {
            throw new BRail_Security_IncorrectTicketUsageException();
        }

        $groups = null;
        if ($this->roleProviderWSDL !== null) {
            $roleProvider = new SoapClient($this->roleProviderWSDL);
            $groups = $roleProvider->GetRolesForUser(
                array(
                    'username'        => $this->loginID,
                    'applicationName' => $this->applicationID,
                    'lcid'            => self::LCID_EN
                )
            )->GetRolesForUserResult
             ->string;
        }

        return new BRail_Security_AuthenticatedUser(
            $userInformation->userName,
            $userInformation->applicationId,
            $userInformation->language,
            $userInformation->clientIpAddress,
            $userInformation->link,
            $userInformation->objectGroupId,
            $userInformation->objectId,
            $userInformation->functionId,
            $groups
        );
    }
}
